﻿/*
 *    NotepadSharp (Notepad#)
 *    Copyright (C) 2013  Josh Finlay

 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.

 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.

 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO;
using System.Media;

namespace NotepadSharp
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        public bool hasChanged = false;
        public string fileName = "Untitled";
        public string fullPath = "";
        public string searchKeyword = "";
        public int lastFindLoc = -1;
        public bool foundMatch = false;

        protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
        {
            if (keyData == Keys.Escape)
            {
                if (toolStripTextBox1.Focused == true)
                {
                    toolStripTextBox1.Clear();
                    searchKeyword = "";
                    lastFindLoc = -1;
                    toolStripTextBox1.Visible = false;
                    foundMatch = false;
                }
            }
            return base.ProcessCmdKey(ref msg, keyData);
        }

        private void cutToolStripMenuItem_Click(object sender, EventArgs e)
        {
            richTextBox1.Cut();
        }

        private void selectAllToolStripMenuItem_Click(object sender, EventArgs e)
        {
            richTextBox1.SelectAll();
        }

        private void statusbarToolStripMenuItem_Click(object sender, EventArgs e)
        {

        }

        private void richTextBox1_TextChanged(object sender, EventArgs e)
        {
            hasChanged = true;
        }

        public bool saveFile()
        {
            if (fullPath == "")
            {
                if (saveFileDialog1.ShowDialog() == DialogResult.OK)
                {
                    richTextBox1.SaveFile(saveFileDialog1.FileName, RichTextBoxStreamType.PlainText);
                    fullPath = saveFileDialog1.FileName;
                    fileName = Path.GetFileName(fullPath);
                    return true;
                }
                else
                {
                    return false;
                }
            }
            else
            {
                richTextBox1.SaveFile(fullPath, RichTextBoxStreamType.PlainText);
                return true;
            }
        }

        private void newToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (hasChanged)
            {
                DialogResult res = MessageBox.Show("Do you want to save changes to " + fileName + "?", "Notepad#", MessageBoxButtons.YesNoCancel, MessageBoxIcon.None);
                if (res == DialogResult.Yes)
                {
                    if (saveFile()) {
                        richTextBox1.Clear();
                        fileName = "Untitled";
                        fullPath = "";
                        hasChanged = false;
                        updateTitle();
                    }
                }
                else if (res == DialogResult.No)
                {
                    richTextBox1.Clear();
                    fileName = "Untitled";
                    fullPath = "";
                    hasChanged = false;
                    updateTitle();
                }
            }
            else 
            {
                    richTextBox1.Clear();
                    fileName = "Untitled";
                    fullPath = "";
                    hasChanged = false;
                    updateTitle();
            }
        }

        public void updateTitle()
        {
            Text = fileName + " - Notepad#";
        }

        public void resetSearch()
        {
            searchKeyword = "";
            lastFindLoc = -1;
            foundMatch = false;
        }

        public void loadFile()
        {
            if (openFileDialog1.ShowDialog() == DialogResult.OK)
            {
                fileName = Path.GetFileName(openFileDialog1.FileName);
                fullPath = openFileDialog1.FileName;
                richTextBox1.LoadFile(openFileDialog1.FileName, RichTextBoxStreamType.PlainText);
                updateTitle();
                hasChanged = false;
                resetSearch();
            }
        }

        private void openToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (hasChanged)
            {
                DialogResult res = MessageBox.Show("Do you want to save changes to " + fileName + "?", "Notepad#", MessageBoxButtons.YesNoCancel, MessageBoxIcon.None);
                if (res == DialogResult.Yes)
                {
                    saveFile();
                }
                if (res != DialogResult.Cancel)
                {
                    loadFile();
                }
            }
            else { loadFile(); }
        }

        private void saveToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (fullPath == "")
            {
                saveAsToolStripMenuItem_Click(sender, e);
            }
            else
            {
                richTextBox1.SaveFile(fullPath);
                hasChanged = false;
            }
        }

        private void saveAsToolStripMenuItem_Click(object sender, EventArgs e)
        {
            string oldPath = fullPath;
            fullPath = "";
            if (saveFile())
            {
                updateTitle();
            }
            else
            {
                fullPath = oldPath;
            }
        }

        private void exitToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (hasChanged)
            {
                DialogResult res = MessageBox.Show("Do you want to save changes to " + fileName + "?", "Notepad#", MessageBoxButtons.YesNoCancel, MessageBoxIcon.None);
                if (res == DialogResult.Yes)
                {
                    saveFile();
                }
                if (res != DialogResult.Cancel)
                {
                    Close();
                }
            }
            else { Close(); }
        }

        private void undoToolStripMenuItem_Click(object sender, EventArgs e)
        {
            richTextBox1.Undo();
        }

        private void copyToolStripMenuItem_Click(object sender, EventArgs e)
        {
            richTextBox1.Copy();
        }

        private void pasteToolStripMenuItem_Click(object sender, EventArgs e)
        {
            richTextBox1.Paste();
        }

        private void deleteToolStripMenuItem_Click(object sender, EventArgs e)
        {
        }

        private void findToolStripMenuItem_Click(object sender, EventArgs e)
        {
            toolStripTextBox1.Visible = true;
            toolStripTextBox1.Focus();
        }

        public void findStr(string str)
        {
            if (str == searchKeyword)
            {
                lastFindLoc = richTextBox1.Find(str, lastFindLoc+1, RichTextBoxFinds.None);
            }
            else
            {
                resetSearch();
                lastFindLoc = richTextBox1.Find(str, RichTextBoxFinds.None);
                searchKeyword = str;
            }
            if (lastFindLoc < 0)
            {
                if (foundMatch == false) MessageBox.Show("Cannot find \"" + searchKeyword + "\"", "Notepad#", MessageBoxButtons.OK, MessageBoxIcon.Information);
                lastFindLoc = -1;
                findStr(str);
            }
            else
            {
                //richTextBox1.SelectionBackColor = Color.Yellow;
                foundMatch = true;
            }
        }

        private void timeDateToolStripMenuItem_Click(object sender, EventArgs e)
        {
            DateTime dt = DateTime.Now;
            string pdt = dt.ToShortTimeString() + " " + dt.ToShortDateString();
            richTextBox1.AppendText(pdt + Environment.NewLine);
        }

        private void wordWrapToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (wordWrapToolStripMenuItem.Checked == true)
            {
                wordWrapToolStripMenuItem.Checked = false;
                richTextBox1.WordWrap = false;
            }
            else
            {
                wordWrapToolStripMenuItem.Checked = true;
                richTextBox1.WordWrap = true;
            }
        }

        private void fontToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (fontDialog1.ShowDialog() == DialogResult.OK)
            {
                richTextBox1.Font = fontDialog1.Font;
            }
        }

        private void findNextToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (searchKeyword != "")
            {
                lastFindLoc = richTextBox1.Find(searchKeyword, lastFindLoc+1, RichTextBoxFinds.None);
                if (lastFindLoc < 0)
                {
                    MessageBox.Show("Cannot find \"" + searchKeyword + "\"", "Notepad#", MessageBoxButtons.OK, MessageBoxIcon.Information);
                    lastFindLoc = -1;
                }
            }
            else
            {
                SystemSounds.Exclamation.Play();
            }
        }

        private void toolStripTextBox1_KeyPress(object sender, KeyPressEventArgs e)
        {
            if (e.KeyChar == 13)
            {
                findStr(toolStripTextBox1.Text);
            }
        }

        private void toolStripMenuItem3_Click(object sender, EventArgs e)
        {
            if (pageSetupDialog1.ShowDialog() == DialogResult.OK)
            {
                MessageBox.Show("Not implemented");
            }
        }

        private void printToolStripMenuItem_Click(object sender, EventArgs e)
        {
            printDialog1.Document = printDocument1;
            if (printDialog1.ShowDialog() == DialogResult.OK)
            {
                printDocument1.PrinterSettings = printDialog1.PrinterSettings;
                StringReader reader = new StringReader(richTextBox1.Text);
                printDocument1.DocumentName = fullPath;
                printDocument1.Print();
            }
        }

        private void printDocument1_PrintPage(object sender, System.Drawing.Printing.PrintPageEventArgs e)
        {
            StringReader reader = new StringReader(richTextBox1.Text);
            float LinesPerPage = 0;
            float YPosition = 0;
            int Count = 0;
            float LeftMargin = e.MarginBounds.Left;
            float TopMargin = e.MarginBounds.Top;
            string Line = null;
            Font PrintFont = this.richTextBox1.Font;
            SolidBrush PrintBrush = new SolidBrush(Color.Black);

            LinesPerPage = e.MarginBounds.Height / PrintFont.GetHeight(e.Graphics);

            while (Count < LinesPerPage && ((Line = reader.ReadLine()) != null))
            {
                YPosition = TopMargin + (Count * PrintFont.GetHeight(e.Graphics));
                e.Graphics.DrawString(Line, PrintFont, PrintBrush, LeftMargin, YPosition, new StringFormat());
                Count++;
            }

            if (Line != null)
            {
                e.HasMorePages = true;
            }
            else
            {
                e.HasMorePages = false;
            }
            PrintBrush.Dispose();
        }

        private void replaceToolStripMenuItem_Click(object sender, EventArgs e)
        {
            MessageBox.Show("TODO");
            
        }

        private void aboutNotepadToolStripMenuItem_Click(object sender, EventArgs e)
        {
            using (Form2 aboutFrm = new Form2())
            {
                aboutFrm.ShowDialog();
            }
        }

        private void Form1_Shown(object sender, EventArgs e)
        {
            string[] args = Environment.GetCommandLineArgs();
            if (args.Length > 1)
            {
                if (File.Exists(args[1]))
                {
                    fileName = Path.GetFileName(args[1]);
                    fullPath = args[1];
                    richTextBox1.LoadFile(args[1], RichTextBoxStreamType.PlainText);
                    updateTitle();
                    hasChanged = false;
                    resetSearch();
                }
                else
                {
                    MessageBox.Show("Unable to open: \"" + args[1] + "\"" + Environment.NewLine + Environment.NewLine + "File does not exist.", "Notepad# Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }
        }
    }
}
